export function diff (oldTree,newTree) {
  let patches = {}
  let currentNode = 0;
  recursion(oldTree,newTree,currentNode,patches);
  return patches;
}

const ATTRS = 'ATTRS';
const TEXT = 'TEXT';
const REMOVE = 'REMOVE';
const REPLACE = 'REPLACE';
const CREATE = 'CREATE';
let globalIndex = 0;

/**
 *
 * @param oldChildren
 * @param newChildren
 * @param index
 * @param patches
 */
export function diffChildren (oldChildren,newChildren,index,patches) {
  newChildren.forEach((child,i)=>{
    recursion(oldChildren[i],child,++globalIndex,patches);
  })
}

export function diffAttr (oldAttrs,newAttrs) {
  let patch = {};
  for(let key in oldAttrs){
    //当新老属性中都具有该属性时,老属性的值与新属性不相同
    //当老属性中有属性,新属性中没有,就会出现undefined的情况,将undefined赋值给新属性
    if(oldAttrs[key] !==newAttrs[key]){
      patch[key] = newAttrs[key];
    }
  }
  for (let key in newAttrs){
    if(!oldAttrs.hasOwnProperty(key)){
      //节点中没有新的属性,直接创建新的属性
      patch[key] = newAttrs[key];
    }
  }
  return patch;
}

//判断String的类型
function isString(node){
  return Object.prototype.toString.call(node) ==='[object String]';
}

/**
 * 递归整个树
 * @param oldNode 新的DOM树
 * @param newNode 旧的DOM树
 * @param index
 * @param patches
 */
function recursion (oldNode,newNode,index,patches) {
  let currentPatch = [];
  //类型一样,比如都是ul li div
  if(!newNode){
    currentPatch.push({type:REMOVE,index})
  }
  else if(!oldNode){
    currentPatch.push({type:CREATE,newNode});
  }
  else if(isString(oldNode)&&isString(newNode)){
    //假设是文本节点,判断文本内容是否一致,如果不一致,需要调用文本补丁
    if(oldNode!==newNode){
      currentPatch.push({type:TEXT,text:newNode})
    }
  }
  else if(oldNode.type === newNode.type){
    //比较属性
    let attrs = diffAttr(oldNode.props,newNode.props);
    if (Object.keys(attrs).length>0){
      currentPatch.push({type:ATTRS,attrs})
    }
    diffChildren(oldNode.children,newNode.children,index,patches);
    // console.log(attrs);
  }else{
    currentPatch.push({type:REPLACE,newNode});
  }
  if(currentPatch.length){
    //补丁包中有值
    patches[index] = currentPatch;
  }
  console.log(patches);
}

export default diff;